package com.gzc.just.play;

import com.gzc.just.play.proto.War3Proto;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;

public class Utils {
    private static final Logger logger = LogManager.getLogger(Utils.class);

    /**
     * 双向转发数据
     * @param srcChannel 源链接
     * @param dstChannel 目标链接
     */
    public static void transferData(AsynchronousSocketChannel srcChannel, AsynchronousSocketChannel dstChannel) {
        logger.info("transferData,srcChannel={},dstChannel={}", srcChannel.toString(), dstChannel.toString());

        int readLen = 0; // 显式初始化
        try {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while (readLen >= 0) {
                readLen = srcChannel.read(buffer).get(); // 获取读取的字节数
                if (readLen > 0) {
                    logger.info("transferData,readLen={}", readLen);
                    buffer.flip();

                    while (buffer.hasRemaining()) {
                        dstChannel.write(buffer).get(); // 使用非阻塞写操作
                        logger.info("transferData,writeLen={}", buffer.remaining());
                    }
                    buffer.clear(); // 清空缓冲区，准备下次读取
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    // 发送protobuf消息
    public static void sendProtobufMessage(AsynchronousSocketChannel channel, War3Proto.War3Message message) throws Exception {
        logger.info("sendProtobufMessage channel={},msgType={},msg={}", channel, message.getType(), message.toString());

        byte[] messageBytes = message.toByteArray();
        ByteBuffer buffer = ByteBuffer.allocate(4 + messageBytes.length);
        buffer.putInt(messageBytes.length);
        buffer.put(messageBytes);
        buffer.flip();
        channel.write(buffer).get();
    }

    public static void closeAsynchronousSocketChannel(AsynchronousSocketChannel asc) {
        try {
            if (null != asc) {
                asc.close();
            }
        } catch (IOException ignored) {
            // nothing to do
        }
    }

}
